上一篇DAY5: Node 的內部機制(一)主要解釋了JavaScript的同步與非同步,相信看完上一篇完再來看今天這篇就會相當好理解了,故建議看這篇之前先瀏覽前一篇。
但前一篇開頭也有提到Node中阻塞與非阻塞,這是針對I/O 的調用。並非可以跟同步與非同步畫上等號,主要是針對的狀態不同,就Node的阻塞與非阻塞I/O 都是同步的,這部分還請多加理解!!
正式進入主題吧!
對於I/O分成數據的準備 與返回的結果,I/O會發出系統回調請求後,就一直處在等待的狀態,等到數據準備與返回結果完成後,再重新運行。
舉個例子:
function dataone(){
var start=new Date().getTime();
while (new Date().getTime()<start+5000);
}
dataone();
console.log("dataone 已更新完畢");
console.log("I am Nicole!!");
console.log("Nicole is me~");
執行結果:
實際處理這段程式碼會發現,當執行dataone
這個的函數的更新,而當dataone
這個函數還沒更新完時,下面三行log
只能等待!而當函數執行完後,才會相繼出現。
而這邊的
dataone();
是屬於直接被調用的情況下,與接下來非阻塞的例子有很大的不同之處。
(這邊特別說明的是例子中的這段
while (new Date().getTime()<start+5000);
可以調整毫秒的時間,只是透過這段執行時可以顯現出等待時間的長短。)
基本和阻塞過程類似,但不同於阻塞的是,如果數據還沒準備完成或是還在處理中,不須等待,直接執行,當數據準備完成再回調出來。
舉個例子:
function dataone(done)
{
setTimeout(()=>
{
done();
}
,5000);
}
dataone(function()
{
console.log("dataone 更新完畢!!")
});
console.log("I am Nicole!!");
console.log("Nicole is me~");
執行結果:
再來:
這邊結果會分成兩段來呈現是因為在dataone
處理過程中需要等待,而等待的過程已經先把下面兩行的log
呈現出來了,當dataone
處理完成後就會顯示dataone
裡面的內容!故分成兩段圖呈現是強調這等待的過程到結果的完整地呈現!
setTimeout()
是指定毫秒數調用函數。(這邊拿來設定我的dataone
處理的時間,跟阻塞的例子一樣可以自己調整等待的毫秒數)。done
是代表回調函數。(告知將要傳遞的函數說參數函數已處理完畢)。
這邊的
setTimeout(()=>
{
done();
}
,5000);
}
是作為參數傳遞給另一個函數
dataone(function()
{
console.log("dataone 更新完畢!!")
});
作為觸發點才會執行回調函數。與阻塞例子中的
dataone();
直接拿來被取用有很大的區別!!!